package com;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import com.zx.handler.LogFormatHandler;
import com.zx.handler.ThreadLocalHandler;
import com.zx.model.ConfContent;
import com.zx.model.log.LogConfContent;
import com.zx.model.log.LogIp;
import com.zx.model.log.LogMode;
import com.zx.model.log.LogPvAndUv;
import com.zx.util.Assert;
import com.zx.util.OutputUtil;
import com.zx.util.PrintlnUtil;
import com.zx.util.ReadNgnixCofUtil;

/**
 * @Project: ngnix_analyze
 * @Title: Main2
 * @Description: 第二个版本的分析器
 * @author: zhangxue
 * @date: 2018年8月4日下午6:00:38
 * @company: alibaba
 * @Copyright: Copyright (c) 2015
 * @version v1.0
 */
public class Main2 {
	
	/** 流量分析 */
	private final static String ARGS_A = "-a";
	
	/** 访问者IP分析 */
	private final static String ARGS_B = "-b";
	
	/** 配置文件的相对路径 */
	private final static String CONF_FILE_PATH = "/conf/nginx.conf";
	
	private final static String HELP_TEXT  = "使用方法：java -jar ngnix_analyze.jar [命令] [参数]\r\n"
				+ "\t第一个参数	【必选】-a或者-b，-a是流量分析， -b是访问者IP分析\r\n"
				+ "\t第二个参数	【必选】true或者false， 是否开启日志\r\n"
				+ "\t第三个参数	【必选】nginx安装目录，比如/media/zhangxue/工作空间/nginx-1.10.3\r\n"
				+ "\t第四个参数	【可选】统计结果输入的位置，比如 /media/zhangxue/工作空间/nginx-1.10.3/a.html\r\n"
				+ "\t输出结果是一个json格式[{'date':'2018-08-01', 'pv':25, 'uv':24}, {'date':'2018-07-31', 'pv':96, 'uv':40}]\r\n";
			
	/**
	 * 程序入库
	 * @Title: 
	 * 		第一个参数	-a或者-b，-a是流量分析， -b是访问者IP分析
	 * 		第二个参数	true或者false， 是否开启日志
	 * 		第三个参数	nginx安装目录，比如/media/zhangxue/工作空间/nginx-1.10.3
	 * 		第四个参数	统计结果输入的位置，比如 /media/zhangxue/工作空间/nginx-1.10.3/a.html
	 * 		输出结果是一个json格式[{'date':'2018-08-01', 'pv':25, 'uv':24}, {'date':'2018-07-31', 'pv':96, 'uv':40}]
	 * @param args
	 * @date: 2018年8月4日下午5:51:22
	 */
	public static void main(String[] args) {//   /media/zhangxue/工作空间/nginx-1.10.3
		try {
			String main = args[0];
			ThreadLocalHandler.openLogPrint.set(Boolean.parseBoolean(args[1]));//设置日志
			String nginxInstallPath = args[2];
			
			if(args.length == 4) {//将数据输出到一个文件中
				String outputFilePath = args[3];
				ThreadLocalHandler.outputFilePath.set(outputFilePath);
			}
			
			if(ARGS_A.equals(main)) {
				commandA(nginxInstallPath);//流量分析,PV，UV
			} else if (ARGS_B.equals(main)) {
				commandB(nginxInstallPath);//commandA
			} else {
				System.out.println(HELP_TEXT);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void commandA(String nginxInstallPath) {
		File nginxInstallDir = new File(nginxInstallPath);
		// 判断安装目录
		if(!nginxInstallDir.exists() || !nginxInstallDir.isDirectory()) {
			System.out.println("nginx安装目录不存在：" + nginxInstallPath);
			return;
		}
		// 判断配置文件
		File configFile = new File(nginxInstallPath + CONF_FILE_PATH);
		if(!configFile.exists() || !configFile.isFile()) {
			System.out.println("nginx配置文件不存在：" + nginxInstallPath);
			return;
		}
		// 读取ngnix配置文件
		List<ConfContent> allConfContents = ReadNgnixCofUtil.readNgnixConfig(configFile);
		// 获得日志格式的解析器
		LogFormatHandler logFormatHandler = new LogFormatHandler(allConfContents);
		// 保存数据
		List<LogMode> allLog = new ArrayList<LogMode>();
		Set<Entry<String, LogConfContent>> entrySet = logFormatHandler.getParseRuleMap().entrySet();
		for (Entry<String, LogConfContent> entry : entrySet) {
			String logFilePath = entry.getValue().getLogFilePath();
			List<LogMode> list = null;
			PrintlnUtil.println("开始解析日志:" + logFilePath);
			// 将日志文件解析为日志通用对象
			if(logFilePath.startsWith("/")) {//日志保持在绝对路径上
				list = logFormatHandler.parseFile(new File(logFilePath));
			} else {
				list = logFormatHandler.parseFile(new File(nginxInstallPath + "/" + logFilePath));
			}
			if(Assert.isNotEmpty(list)) {
				allLog.addAll(list);
			}
		}
		// 1. 进行pv和uv的分析
		PrintlnUtil.println("######################进行PV和UV分析############################");
		List<LogPvAndUv> stat = LogPvAndUv.stat(allLog);
		System.out.println(Arrays.toString(stat.toArray()));
		PrintlnUtil.println("######################分析完毕############################");
		// 输出结果到文件中
		if(Assert.isNotEmpty(ThreadLocalHandler.outputFilePath.get())) {
			OutputUtil.outputTextToFile(Arrays.toString(stat.toArray()), ThreadLocalHandler.outputFilePath.get());
		}
	}
	
	private static void commandB(String nginxInstallPath) {
		File nginxInstallDir = new File(nginxInstallPath);
		// 判断安装目录
		if(!nginxInstallDir.exists() || !nginxInstallDir.isDirectory()) {
			System.out.println("nginx安装目录不存在：" + nginxInstallPath);
			return;
		}
		// 判断配置文件
		File configFile = new File(nginxInstallPath + CONF_FILE_PATH);
		if(!configFile.exists() || !configFile.isFile()) {
			System.out.println("nginx配置文件不存在：" + nginxInstallPath);
			return;
		}
		// 读取ngnix配置文件
		List<ConfContent> allConfContents = ReadNgnixCofUtil.readNgnixConfig(configFile);
		// 获得日志格式的解析器
		LogFormatHandler logFormatHandler = new LogFormatHandler(allConfContents);
		// 保存数据
		List<LogMode> allLog = new ArrayList<LogMode>();
		Set<Entry<String, LogConfContent>> entrySet = logFormatHandler.getParseRuleMap().entrySet();
		for (Entry<String, LogConfContent> entry : entrySet) {
			String logFilePath = entry.getValue().getLogFilePath();
			List<LogMode> list = null;
			PrintlnUtil.println("开始解析日志:" + logFilePath);
			// 将日志文件解析为日志通用对象
			if(logFilePath.startsWith("/")) {//日志保持在绝对路径上
				list = logFormatHandler.parseFile(new File(logFilePath));
			} else {
				list = logFormatHandler.parseFile(new File(nginxInstallPath + "/" + logFilePath));
			}
			if(Assert.isNotEmpty(list)) {
				allLog.addAll(list);
			}
		}
		
		// 进行IP统计分析
		PrintlnUtil.println("######################进行IP统计分析############################");
		List<LogIp> ipStat = LogIp.stat(allLog);
		System.out.println(Arrays.toString(ipStat.toArray()));
		PrintlnUtil.println("######################分析完毕############################");
		// 输出结果到文件中
		if(Assert.isNotEmpty(ThreadLocalHandler.outputFilePath.get())) {
			OutputUtil.outputTextToFile(Arrays.toString(ipStat.toArray()), ThreadLocalHandler.outputFilePath.get());
		}
	}
	
}
